Conventional hard memory controllers (which may also herein be referred to as memory interfaces) are generally designed for controlling (or interfacing with) a memory of a particular data width. For example, a conventional hard memory controller may be designed to control a memory of 32 bits or 64 bits. As used herein a hard memory controller is constructed using hard logic that is not configurable for a function other than that of a memory controller. This contrasts with a soft logic memory controller which is configured/programmed to function as a memory controller, but can also be configured/programmed to serve other functions.
Some conventional hard memory controllers allow for using the memory controller for the maximum data width for which the memory controller is designed as well as some data width(s) smaller than the maximum data width. For example, some conventional memory controllers capable of controlling a 64 bits memory may also be used to control a 32 bits wide memory. This provides some flexibility. However, it does so at the expense of wasted hardware when the memory controller is used to control memory of a data width less than the maximum data width that the memory controller is capable of controlling. Thus, with conventional hard memory controller designs, supporting multiple memory data widths can be very expensive since each different memory data width must have hardware built which covers at least that data width.
Moreover, with conventional hard memory controller designs, supporting multiple memory data width combinations can be very expensive since hardware must be built which covers all the combinations. For example, supporting the combinations of (1) two 64 bits wide memories, (2) one 64 bits wide memory, and (3) four 32 bits wide memories would require (a) two 64 bits wide memory controllers and four 32 bits wide memory controllers, without the option of using a 64 bits wide memory controller as a 32 bits wide memory controller, or (b) two 64 bits wide memory controllers and two 32 bits wide memory controllers, with the option of using a 64 bits wide memory controller as a 32 bits wide memory controller. However, using the two 64 bits wide memory controllers and two 32 bits wide memory controllers to support four 32 bits wide memories amounts to wasting some of the resources of the 64 bits wide memory controllers. Also, it involves use of multiplexer(s) for selecting between using the 64 bits wide memory controllers as 64 bits wide memory controllers or 32 bits wide memory controllers.